#include "ASLog.h"
#include "..\base\ASStdLib.h"
#include <stdarg.h>

#define AS_LOG_FILE "appsuit.log"

#ifdef AS_LOG_ENABLE

static ASINT s_as_log_hdlr = -1;
static ASCHAR* s_file_name;
static ASUINT s_file_line;
static ASCHAR s_file_name_store[32];
static ASCHAR s_log_buffer[2 << 10];
static ASCHAR* as_log_pick_up_file_name(ASCHAR* file_name)
{
    ASINT i, len;

    if(!file_name || strlen(file_name) <= 0)
    {
        strcpy(s_file_name_store, "unknown");
        return s_file_name_store;
    }

    memset(s_file_name_store, 0, sizeof(s_file_name_store));
    len = strlen(file_name);

    for(i = len; i >= 0; i--)
    {
        if(*(file_name + i) == '\\')
            break;
    }

    strncpy(s_file_name_store, file_name + i + 1, len - (i + 1));
    return s_file_name_store;
}

ASINT as_log_locate(ASCHAR* file_name, ASUINT file_line)
{
    if(!file_name || strlen(file_name) <= 0)
        return FALSE;

    s_file_name = as_log_pick_up_file_name(file_name);
    s_file_line = file_line;
    return TRUE;
}

void as_log_init(void)
{
#if defined(AS_RUN_ON_MRE)
    ASCHAR* tmp_path;
    ASWCHAR* w_tmp_path;
    ASINT driver = vm_get_removable_driver();

    if(driver < 0)
    {
        driver = vm_get_system_driver();
    }

    tmp_path = as_calloc(32 * sizeof(ASCHAR));

    if(!tmp_path)
        return;

    as_sprintf(tmp_path, "%c:\\%s", driver, AS_LOG_FILE);
    w_tmp_path = as_calloc(32 * sizeof(ASWCHAR));

    if(!w_tmp_path)
        return;

    vm_ascii_to_ucs2(w_tmp_path, 32 * sizeof(ASWCHAR), tmp_path);
    s_as_log_hdlr = as_file_open(w_tmp_path, AS_FILE_NEW);

    if(tmp_path)
        as_free(tmp_path);

    if(w_tmp_path)
        as_free(w_tmp_path);

#elif defined(AS_RUN_ON_SKY)
    s_as_log_hdlr = as_file_open(AS_LOG_FILE, AS_FILE_NEW);
#endif
}

void as_log_deinit(void)
{
    if(s_as_log_hdlr >= 0)
    {
        as_file_close(s_as_log_hdlr);
        s_as_log_hdlr = -1;
    }
}

static ASCHAR* as_get_tmp_buf(void)
{
    as_memset(s_log_buffer, 0, sizeof(s_log_buffer));
    return s_log_buffer;
}

void _as_log(ASCHAR* cmd, ...)
{
    va_list ap;
    ASCHAR* buffer;
    as_time tm;
    ASINT written;
    buffer = as_get_tmp_buf();

    if(!buffer || s_as_log_hdlr < 0)
        return;

    as_get_time(&tm);
    as_sprintf(buffer, "[%d-%02.2d-%02.2d %02.2d:%02.2d:%02.2d][FILE:%s][LINE:%d]", tm.year, tm.month, tm.day, tm.hour,
               tm.minute, tm.second, s_file_name, s_file_line);
    va_start(ap, cmd);
    vsprintf(buffer + as_strlen(buffer), cmd, ap);
    va_end(ap);
    as_strcat(buffer, "\n\0");
    as_file_write(s_as_log_hdlr, buffer, (ASUINT)as_strlen(buffer), &written);
}

void _as_log_str(ASCHAR* content)
{
    ASINT written;
    as_time tm;
    ASCHAR* buffer;
    buffer = as_calloc(512);

    if(s_as_log_hdlr < 0 || !content)
        return;

    as_get_time(&tm);
    as_sprintf(buffer, "[%d-%02.2d-%02.2d %02.2d:%02.2d:%02.2d][FILE:%s][LINE:%d]", tm.year, tm.month, tm.day, tm.hour,
               tm.minute, tm.second, s_file_name, s_file_line);
    as_file_write(s_as_log_hdlr, buffer, as_strlen(buffer), &written);
    as_file_write(s_as_log_hdlr, content, as_strlen(content), &written);
    as_sprintf(buffer, "\n\0");
    as_file_write(s_as_log_hdlr, buffer, as_strlen(buffer), &written);
    as_free(buffer);
}

void _as_log_binary(ASCHAR* content, ASINT len)
{
    ASCHAR* buffer;
    as_time tm;
    ASINT written;
    buffer = as_calloc(512);

    if(!buffer || s_as_log_hdlr < 0 || !content || len <= 0)
        return;

    as_get_time(&tm);
    as_sprintf(buffer, "[%d-%02.2d-%02.2d %02.2d:%02.2d:%02.2d][FILE:%s][LINE:%d]\n", tm.year, tm.month, tm.day, tm.hour,
               tm.minute, tm.second, s_file_name, s_file_line);
    as_file_write(s_as_log_hdlr, buffer, (ASUINT)as_strlen(buffer), &written);
    as_file_write(s_as_log_hdlr, content, len, &written);
    as_free(buffer);
}

#ifdef WIN32
#pragma pack(push,1)
#endif

typedef struct
{
    ASUINT16  bfType;
    ASUINT32 bfSize;
    ASUINT16  bfReserved1;
    ASUINT16  bfReserved2;
    ASUINT32 bfOffBits;
} bitmap_file_header;

typedef struct
{
    ASUINT32 biSize;
    ASINT32 biWidth;
    ASINT32 biHeight;
    ASUINT16 biPlanes;
    ASUINT16 biBitCount;
    ASUINT32 biCompression;
    ASUINT32 biSizeImage;
    ASINT32 biXPelsPerMeter;
    ASINT32 biYPelsPerMeter;
    ASUINT32 biClrUsed;
    ASUINT32 biClrImportant;
} bitmap_info_header;

typedef struct
{
    ASUINT8    rgbBlue;
    ASUINT8    rgbGreen;
    ASUINT8    rgbRed;
    ASUINT8    rgbReserved;
} rgb_quad;
#ifdef WIN32
#pragma pack(pop)
#endif

/*
color matrix data:
all pixels aligned from bottom to up,from left to right.
RGB data aligned as B,G,R
*/
//void as_snapshot_layer_to_bmp(ASINT layer, ASWCHAR* file_path)
//{
//    ASINT fh;
//    ASUINT8* layer_buf;
//    bitmap_file_header file_header;
//    bitmap_info_header info_header;
//    rgb_quad rgb_info;
//    ASUINT lcd_w, lcd_h, written, data_len;
//
//    if((layer != 0 && layer != 1) || !file_path || as_wstrlen(file_path) <= 0)
//        return;
//
//    lcd_w = as_get_lcd_width();
//    lcd_h = as_get_lcd_height();
//    file_header.bfType = 0x4D42;
//    file_header.bfReserved1 = 0;
//    file_header.bfReserved2 = 0;
//    file_header.bfOffBits = sizeof(bitmap_file_header) + sizeof(bitmap_info_header) + sizeof(rgb_quad);
//    file_header.bfSize = file_header.bfOffBits + lcd_w * lcd_h * 2;
//    info_header.biSize = sizeof(bitmap_info_header);
//    info_header.biWidth = lcd_w;
//    info_header.biHeight = lcd_h;
//    info_header.biPlanes = 1;
//    info_header.biBitCount = 16;
//    info_header.biCompression = 3/*BI_BITFIELDS*/;
//    info_header.biSizeImage = 0;
//    info_header.biXPelsPerMeter = 0;
//    info_header.biYPelsPerMeter = 0;
//    info_header.biClrUsed = 0;
//    info_header.biClrImportant = 0;
//    rgb_info.rgbBlue = 0x001F;
//    rgb_info.rgbGreen = 0x07E0;
//    rgb_info.rgbRed = 0xF800;
//    rgb_info.rgbReserved = 0x0;
//    fh = as_file_open(file_path, AS_FILE_NEW, TRUE);
//
//    if(fh < 0)
//        return;
//
//    as_file_write(fh, &file_header, sizeof(bitmap_file_header), &written);
//    as_file_write(fh, &info_header, sizeof(bitmap_info_header), &written);
//    as_file_write(fh, &rgb_info, sizeof(rgb_info), &written);
//    //layer_buf = vm_graphic_get_layer_buffer(layer);
//    written = 0;
//    data_len = lcd_w * lcd_h * 2;
//
//    while (written < data_len)
//    {
//        ASUINT w;
//        as_file_write(fh, layer_buf, data_len - written, &w);
//        written += w;
//    }
//
//    as_file_close(fh);
//}

#endif//AS_LOG_ENABLE

